﻿#ifndef _EASYTCPSERVER_H_
#define _EASYTCPSERVER_H_

#include <vector>
#include <atomic>
#include "CELL.h"
#include "CELLTimestamp.hpp"
#include "CELLTask.hpp"
#include "INetEvent.h"
#include "CELLServer.h"
#include "CELLClient.h"
#include "CELLTimer.hpp"

/*
	用于接收新的客户端口，并添加到消费者线程中的客户端缓冲队列，也进行着统计收发包数量的工作
*/
class EasyTcpServer : public INetEvent
{
private:
	//描述本类线程对象信息
	CELLThread _thread;
	// 存储着的多个CELLServer对象，用于给对象中的客户端缓冲队列中添加新加入的客户端
	// 每一个CELLServer都会创建一个线程用对象的OnRun作为线程入口函数
	std::vector<CELLServer*> _cellServers;
	// 每秒消息计数
	CELLTimestamp _tTime;
	// 监听套接字
	SOCKET _sock = INVALID_SOCKET;
public:
	EasyTcpServer();

	virtual ~EasyTcpServer();

	// 初始化socket
	SOCKET InitSocket();
	// 绑定IP和端口
	int Bind(const char *ip, unsigned short port);

	// 监听端口
	int Listen(int backlog);

	// 关闭socket
	void Close();

	// 创建CELLServer
	template<typename ServerT>
	void Start(int nCELLServer);

	// 接收客户端连接
	SOCKET Accept();

	void AddClientToCELLServer(CELLClient* pClient);

	// 客户端加入事件，由主线程一个线程调用
	virtual void OnNetJoin(CELLClient* pClient);

	// 客户端断开连接事件，由CELLServer多个线程调用 不安全
	virtual void OnNetLeave(CELLClient* pClient);

	// 客户端消息事件，由CELLServer多个线程调用 不安全
	virtual void OnNetMsg(CELLServer* pCELLServer, CELLClient* pCLient, DataHeader* header);

	virtual void OnNetRecv(CELLClient* pCLient);

	// 注册时间事件，单位(秒)
	unsigned int add_time_event(CELLTimer::time_callback cb, void *ctx, unsigned int after_sec, int repeat = 1);
	// 更新时间事件，单位(秒)
	void mod_time_event(unsigned int timerid, unsigned int after_sec, int repeat = 1);
	// 删除时间事件，单位(秒)
	void del_time_event(unsigned int timerid);
protected:
	// 定时事件处理
	CELLTimer _time_event;
	// 处理网络消息
	virtual void OnRun(CELLThread* pthread) = 0;

	// 处理消息，响应网络消息
	void time4msg();

	SOCKET sockfd();

	// recv函数计数
	std::atomic<int> _recvCount{ 0 };
	// 客户端连接数
	std::atomic<int> _clientCount{ 0 };
	// 客户端断开连接数
	std::atomic<int> _leaveCount{ 0 };
	// 收到消息计数
	std::atomic<int> _recvMsg{ 0 };
	// 接收新客户端时判断是否到了连接上限
	int _nMaxClient;
	// 创建新的CELLClient时候指定接收缓冲区和发送给缓冲区的大小
	int _nSendBuffSize;
	int _nRecvBuffSize;
};

// 创建CELLServer
template<typename ServerT>
void EasyTcpServer::Start(int nCELLServer)
{
	for (int i = 0; i < nCELLServer; ++i)
	{
		ServerT* ser = new ServerT();
		ser->SetId(i + 1);
		_cellServers.push_back(ser);
		// 设置事件对象，用于调用本对象的onNetLeave，OnNetMsg等事件处理函数
		ser->SetEventObj(this);
		// 在这个方法中会创建一个线程开启任务
		ser->Start();
	}
	// 让本任务也作为一个线程启动
	_thread.Start(
		// onCreate
		nullptr,
		// onRun
		[this](CELLThread* pthread) {
			OnRun(pthread);
		}
	);
}

#endif // #ifndef _EASYTCPSERVER_H_
